package com.darco.darcoapp;
import android.text.method.HideReturnsTransformationMethod;
import android.util.Log;
import android.widget.Toast;
import eneter.messaging.diagnostic.EneterTrace;
import eneter.messaging.endpoints.typedmessages.*;
import eneter.messaging.messagingsystems.httpmessagingsystem.HttpMessagingSystemFactory;
import eneter.messaging.messagingsystems.messagingsystembase.*;
import eneter.messaging.messagingsystems.tcpmessagingsystem.TcpMessagingSystemFactory;
import eneter.messaging.messagingsystems.websocketmessagingsystem.WebSocketMessagingSystemFactory;
import DARCOShared.requests.*;
import DARCOShared.responses.*;
import DARCOShared.utils.MachineSpecificConstants;
import DARCOShared.utils.NetUtils;

public class MessagingManager {
	// Sender sending MyRequest and as a response receiving MyResponse.
	private IDuplexTypedMessageSender<ResponseWrapper, RequestWrapper> mySender;
	//private Handler myEventHandler = new Handler(); //usato per reinstradare sul thread UI
	private static String serverIP = null;

	public boolean ConnectToServer(MessagingActivity subscriber){
		try
		{
			// Create sender sending MyRequest and as a response receiving MyResponse
			IDuplexTypedMessagesFactory aSenderFactory = new DuplexTypedMessagesFactory();
			mySender = aSenderFactory.createDuplexTypedMessageSender(ResponseWrapper.class, RequestWrapper.class);

			// Iscrive l'activity richiedente ai segnali di risposta in modo che possa ottenerli
			mySender.responseReceived().subscribe(subscriber.myOnResponseHandler);

			// Create TCP messaging for the communication.
			// Note: 10.0.2.2 is a special alias to the loopback (127.0.0.1)
			//       on the development machine
			//IMessagingSystemFactory aMessaging = new WebSocketMessagingSystemFactory();
			IMessagingSystemFactory aMessaging = new TcpMessagingSystemFactory();
			
			//IDuplexOutputChannel anOutputChannel = aMessaging.createDuplexOutputChannel("http://" + NetUtils.getServerIP() +":8060/darco");
			IDuplexOutputChannel anOutputChannel;
			if(serverIP == null){
			try {
				serverIP = NetUtils.getLocalServerIP();
				anOutputChannel = aMessaging.createDuplexOutputChannel("tcp://" + serverIP +":8060");
				mySender.attachDuplexOutputChannel(anOutputChannel);
				return true;
			} catch (Exception e) {
				serverIP = NetUtils.getServerIP();
				anOutputChannel = aMessaging.createDuplexOutputChannel("tcp://" + serverIP +":8060");
				mySender.attachDuplexOutputChannel(anOutputChannel);
				return true;
			}
			}
			else{
				anOutputChannel = aMessaging.createDuplexOutputChannel("tcp://" + serverIP +":8060");
				mySender.attachDuplexOutputChannel(anOutputChannel);
				return true;
			}
			
		}
		catch (Exception err)
		{
			Toast.makeText(subscriber.getApplicationContext(), "Failed to connect to server! (No internet connection? Server down? Firewall?)", Toast.LENGTH_LONG).show();
			EneterTrace.error("Open connection failed.", err);
		}
		return false;
	}
	
	public boolean SendRequest(RequestBase rq, MessagingActivity sender)
    {
        // Send the request message.
		RequestWrapper rw = new RequestWrapper(rq);
        try
        {
            mySender.sendRequestMessage(rw);
            return true;
        }
        catch (Exception err)
        {
        	Toast.makeText(sender.getApplicationContext(), "Request failed, cannot communicate with the server!", Toast.LENGTH_SHORT).show();
            EneterTrace.error("Sending the message failed.", err);
        }
        return false;
    }
	
	public void CloseConnection(){
		mySender.detachDuplexOutputChannel();
	}
     
}